package com.wanghaoran.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wanghaoran.dto.*;
import com.wanghaoran.entity.School;
import com.wanghaoran.excel.RoomExcel;
import com.wanghaoran.excel.SchoolExcel;
import com.wanghaoran.exception.IllegalParamException;
import com.wanghaoran.exception.ServerErrorException;
import com.wanghaoran.exception.VersionException;
import com.wanghaoran.mapper.SchoolMapper;
import com.wanghaoran.service.SchoolService;
import com.wanghaoran.vo.SchoolVO;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wanghaoran
 */
@Service
@CacheConfig(cacheNames = "school")
public class SchoolServiceImpl implements SchoolService {

    @Resource
    private SchoolMapper schoolMapper;

    @CacheEvict(allEntries = true)
    @Override
    public int insert(SchoolInsertDTO dto) {
        School school = BeanUtil.copyProperties(dto, School.class);
        // 设置默认值
        if(StrUtil.isBlank(dto.getInfo())) {
            school.setInfo("暂无描述");
        }
        school.setAddress("暂无地址");
        school.setVersion(0L);
        school.setDeleted(0);
        school.setCreated(LocalDateTime.now());
        school.setUpdated(LocalDateTime.now());
        // DB添加
        int result = schoolMapper.insert(school);
        if (result < 0) {
            throw new ServerErrorException("DB添加失败");
        }
        return result;
    }

    @Cacheable(key = "#p0", condition = "#p0 != null", unless = "#result == null")
    @Override
    public School select(Long id) {
        // DB查询
        School result = schoolMapper.select(id);
        if(ObjectUtil.isNull(result)) {
            throw new ServerErrorException("ID不存在");
        }
        return result;
    }

    @Cacheable(key = "#root.methodName", unless = "#result == null")
    @Override
    public List<SchoolVO> list() {
        return schoolMapper.list(new SchoolPageDTO())
                .stream()
                .map(school -> {
                    SchoolVO schoolVO = BeanUtil.copyProperties(school, SchoolVO.class);
                    if (ObjectUtil.isNotNull(school.getTitle())) {
                        schoolVO.setTitle(school.getTitle());
                    }
                    if (ObjectUtil.isNotNull(school.getCollege())) {
                        schoolVO.setCollege(school.getCollege());
                    }
                    if (ObjectUtil.isNotNull(school.getMajor())) {
                        schoolVO.setMajor(school.getMajor());
                    }
                    if (ObjectUtil.isNotNull(school.getClazz())) {
                        schoolVO.setClazz(school.getClazz());
                    }
                    return schoolVO;
                })
                .collect(Collectors.toList());
    }

    @Cacheable(key = "#root.methodName + ':' + #p0.toString()",
                condition = "#p0 != null",
                unless = "#result == null")
    @Override
    public PageInfo<School> page(SchoolPageDTO dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
        return new PageInfo<>(schoolMapper.list(dto));
    }

    @CacheEvict(allEntries = true)
    @Transactional
    @Retryable(retryFor = VersionException.class)
    @Override
    public int update(SchoolUpdateDTO dto) {
        Long id = dto.getId();
        if(ObjectUtil.isNull(id)) {
            throw new IllegalParamException("ID为空");
        }
        School school = schoolMapper.select(id);
        if(ObjectUtil.isNull(school)) {
            throw new ServerErrorException("记录不存在");
        }
        BeanUtil.copyProperties(dto, school);
        // 设置默认值
        school.setUpdated(LocalDateTime.now());
        // DB修改
        int result = schoolMapper.update(school);
        if (result <= 0) {
            throw new VersionException("DB修改失败");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int delete(Long id) {
        int result = schoolMapper.delete(id);
        if (result <= 0) {
            throw new ServerErrorException("DB删除失败");
        }
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public int deleteBatch(List<Long> ids) {
        int result = schoolMapper.deleteBatch(ids);
        if (result <= 0) {
            throw new ServerErrorException("DB批量删除失败");
        }
        return result;
    }

    @Override
    public List<SchoolExcel> getExcelData() {
        return schoolMapper.list(new SchoolPageDTO())
                .stream()
                .map(school -> BeanUtil.copyProperties(school, SchoolExcel.class))
                .collect(Collectors.toList());
    }


}
